home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-05-30 | 4.7 KB | 157 lines | [TEXT/ttxt] |
- // This may look like C code, but it is really -*- C++ -*-
- /*
- ************************************************************************
- *
- * Grayscale Image
- *
- * Read an image from a Portable GrayMap (pgm) file
- *
- * The program reads a "binary" (RAWBITS) pgm file of the following format
- * - A "magic number" for identifying the file type. A pgm
- * file's RAWBITS magic number is the two characters "P5".
- * - Whitespace (blanks, TABs, CRs, LFs).
- * - A width, formatted as ASCII characters in decimal.
- * - Whitespace.
- * - A height, again in ASCII decimal.
- * - Whitespace.
- * - The maximum gray value, again in ASCII decimal. For RAWBITS pgm file
- * the maximum grayscale value cannot exceed 255.
- * - A _single_ character of whitespace (typically a newline).
- * - Width * height gray values, each as plain bytes, between
- * 0 and the specified maximum value, stored consecutivly,
- * starting at the top-left corner of the graymap, proceding in normal
- * English reading order.
- * A value of 0 means black, and the maximum value means white.
- *
- * For more detail, see documentation on PBMPLUS package (specifically,
- * pgm(5)).
- *
- * $Id: read_pgm.cc,v 2.0 1995/03/06 20:57:48 oleg Exp oleg $
- *
- ************************************************************************
- */
-
- #include "image.h"
- #include "endian_io.h"
- #include <iostream.h>
- #include <ctype.h>
-
- /*
- *------------------------------------------------------------------------
- * Class PGMFile
- * designed to contain the control info about the image
- * as defined in the Portable GrayMap file
- */
-
- class PGMFile : public PixelPrimAction
- {
- EndianIn& inf; // stream to read from
- card pixmap_width; // Dimensions of the graymap
- card pixmap_height;
- card max_gray_value; // Maximum value of a graymap pixel
- card pixmap_depth; // ceil(log2(max_gray_value))
-
- void operation(GRAY& pixel);
-
- public:
- PGMFile(EndianIn& _inf);
- void info(void) const; // Dump the header information
- const char * q_name(void) const { return ""; }
- card q_nrows(void) const { return pixmap_height; }
- card q_ncols(void) const { return pixmap_width; }
- card q_depth(void) const { return pixmap_depth; }
- };
-
- /*
- *------------------------------------------------------------------------
- * Construct the PGMFile
- * by reading the header of a PGM file
- */
-
- PGMFile::PGMFile(EndianIn& file) : inf(file)
- {
- const char * magic_str = "P5";
- char read_magic_str[3];
- read_magic_str[0] = inf.read_byte("Reading magic string");
- read_magic_str[1] = inf.read_byte("Reading magic string");
- read_magic_str[2] = '\0';
- if( strcmp(read_magic_str,magic_str) != 0 )
- _error("Read magic string '%s' is not what's expected '%s':"
- "it's not a Portable GrayMap (PGM) file",read_magic_str,magic_str);
-
- if( !(inf >> pixmap_width) )
- _error("Failed to read the number of columns (graymap width)");
-
- if( !(inf >> pixmap_height) )
- _error("Failed to read the number of rows (graymap height)");
-
-
- if( !(inf >> max_gray_value) )
- _error("Failed to read the maximum gray value in the map");
-
- char c;
- assert( inf.get(c) );
- assure( isspace(c), "Failed to get a single space after the header");
-
- assert( pixmap_width > 0 && pixmap_height > 0 && max_gray_value > 0);
-
- if( max_gray_value > 255 )
- _error("Can't handle the graymap with the maximum gray value, %d, "
- "greater than 255",max_gray_value);
-
- {
- int t;
- for(pixmap_depth=0,t=1; t < max_gray_value+1; pixmap_depth++, t *= 2)
- ;
- }
- }
-
- /*
- *------------------------------------------------------------------------
- * Print out all the control information pertaining to the
- * X Window Image read
- */
-
- void PGMFile::info(void) const
- {
- cout << "\n\n=====>The following Portable GrayMap has been read";
- cout << "\nPixmap depth: " << pixmap_depth;
- cout << "\nPixmap width: " << pixmap_width;
- cout << "\nPixmap height: " << pixmap_height;
- cout << "\nMax gray value: " << max_gray_value;
-
- cout << "\n-----End of PGM information\n";
- }
-
- /*
- *------------------------------------------------------------------------
- * Read a pixelmap
- */
-
- void PGMFile::operation(GRAY& pixel)
- {
- pixel = inf.read_byte("reading the pixel matrix");
- }
-
- /*
- *========================================================================
- * Root module - actual IMAGE constructor
- */
-
- void IMAGE::read_pgm(EndianIn& file, const bool print_header_info)
- {
- message("Reading the Portable GrayMap (PGM)\n");
-
- PGMFile pgmfile(file);
-
- if( print_header_info )
- pgmfile.info();
-
- allocate(pgmfile.q_nrows(),pgmfile.q_ncols(),pgmfile.q_depth());
-
- apply(pgmfile);
-
- cout << "\n" << ncols << "x" << nrows << "x" << bits_per_pixel << " image '"
- << name << "' has been read" << endl;
- }
-